package org.little.context.annotation;

import org.little.beans.BeanDefinition;
import org.little.beans.factory.annotation.AnnotatedBeanDefinition;
import org.little.beans.factory.support.BeanDefinitionRegistry;
import org.little.beans.factory.support.BeanNameGenerotor;
import org.little.core.io.AnnotationAttributes;
import org.little.core.type.AnnotationMetadata;
import org.little.util.ClassUtils;
import org.little.util.StringUtils;

import java.beans.Introspector;
import java.util.Set;

/**
 * @author Tinyspot
 * @date 2022-05-24 08:08
 */
public class AnnotationBeanNameGenerator implements BeanNameGenerotor {

    @Override
    public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry registry) {
        if (beanDefinition instanceof AnnotatedBeanDefinition) {
            String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) beanDefinition);
            if (StringUtils.hasText(beanName)) {
                return beanName;
            }
        }
        return buildDefaultBeanName(beanDefinition, registry);
    }

    protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition beanDefinition) {
        AnnotationMetadata metadata = beanDefinition.getMetadata();
        Set<String> types = metadata.getAnnotationTypes();
        String beanName = null;
        for (String type : types) {
            AnnotationAttributes attributes = metadata.getAnnotationAttributes(type);
            if (attributes.get("value") != null) {
                Object value = attributes.get("value");
                if (value instanceof String) {
                    String strValue = (String) value;
                    if (StringUtils.hasLength(strValue)) {
                        beanName = strValue;
                    }
                }
            }
        }
        return beanName;
    }

    protected String buildDefaultBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry registry) {
        return buildDefaultBeanName(beanDefinition);
    }

    protected String buildDefaultBeanName(BeanDefinition definition) {
        String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());
        return Introspector.decapitalize(shortClassName);
    }
}
